scooter.ts ➔ degrees2Radius   B
last analyzed

Complexity

Conditions 8

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 7.3333
c 0
b 0
f 0
cc 8
1
import { API_KEY } from '@env';
2
import config from '../config/config.json';
3
import storage from './storage';
4
5
const scooterModel = {
6
7
    /**
8
     * Get all scooters from API
9
     * @param API_KEY 
10
     * @param city 
11
     * @returns 
12
     */
13
    getScooters: async function getScooters(city: object): Promise<object> {
14
        const token = await storage.readToken();
15
16
        const cityName = city['name'];
17
        const response = await fetch(`${config.base_url}scooters/owner/${cityName}?api_key=${API_KEY}`, {
18
            method: 'GET',
19
            headers: {
20
                'x-access-token': token['token']
21
            }
22
        });
23
        const result = await response.json();
24
        // console.log(result);
25
        
26
        return result;
27
    },
28
29
    sortAvailableScooters: function sortAvailableScooters(scooters: string[]) {
30
        const availableScooters = [];
31
        
32
        for (let i = 0; i < scooters.length; i++) {
33
            if (scooters[i]['status'] === 'Available') {
34
                availableScooters.push(scooters[i])
35
            }
36
        }
37
        
38
        return availableScooters;
39
    },
40
41
    startScooter: async function startScooter(scooterId: string, position: object, scooterPosition: object) {
42
        const token = await storage.readToken();
43
        const user = await storage.readUser();
44
        const maxDistance2Scooter = 20;
45
46
        const userId = user['userData']['id'];        
47
        
48
        const distance2User = scooterModel.getProximity(position, scooterPosition);
49
50
        /**
51
         * Check if user is close enough to unlock the scooter
52
         * Change config.json distanceLimit to 0 to disable this
53
         */
54
        if (distance2User > maxDistance2Scooter && config.distanceLimit === 1) {
55
            const message = {
56
                errors: {
57
                    title: 'You are too far away from this scooter'
58
                }
59
            }
60
61
            return message;
62
        }
63
64
65
        const body = {
66
            'scooter_id': `${scooterId}`,
67
            'user_id': `${userId}`,
68
            'api_key': `${API_KEY}`
69
        };
70
        
71
        // Prepare body to be urlencoded
72
        const formBody = [];
73
74
        for (const property in body) {
75
            const encodedKey = encodeURIComponent(property);
76
            const encodedValue = encodeURIComponent(body[property]);
77
                formBody.push(encodedKey + "=" + encodedValue);
78
        };
79
        
80
        const requestBody = formBody.join("&");
81
82
        // Send POST request
83
        const response = await fetch(`${config.base_url}scooters/rent`, {
84
            method: 'POST',
85
            headers: {
86
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
87
                'x-access-token': token['token']
88
            },
89
            body: requestBody
90
        });
91
92
        if (response.status === 204) {
93
            const message = {
94
                message: 'Journey started',
95
            };
96
97
            return message;
98
        };
99
100
        const result = await response.json();
101
        
102
        return result;
103
    },
104
105
    stopScooter: async function stopScooter(scooterId: string) {
106
        const token = await storage.readToken();
107
        const user = await storage.readUser();
108
109
        const userId = user['userData']['id'];
110
111
        const body = {
112
            'scooter_id': `${scooterId}`,
113
            'user_id': `${userId}`,
114
            'api_key': `${API_KEY}`
115
        };
116
        
117
        // Prepare body to be urlencoded
118
        const formBody = [];
119
120
        for (const property in body) {
121
            const encodedKey = encodeURIComponent(property);
122
            const encodedValue = encodeURIComponent(body[property]);
123
                formBody.push(encodedKey + "=" + encodedValue);
124
        };
125
        
126
        const requestBody = formBody.join("&");
127
128
        // Send POST request
129
        const response = await fetch(`${config.base_url}scooters/stop`, {
130
            method: 'POST',
131
            headers: {
132
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
133
                'x-access-token': token['token']
134
            },
135
            body: requestBody
136
        });
137
138
        if (response.status === 200) {
139
            const message = {
140
                message: 'Journey ended'
141
            };
142
143
            return message;
144
        };
145
146
        const result = await response.json();
147
        
148
        return result;
149
    },
150
151
    getProximity: function getProximity(userPosition, scooterPosition) {
152
        
153
        function degrees2Radius(deg) {
154
            return deg * (Math.PI/180)
155
        };
156
157
        const lat1 = userPosition['latitude'];
158
        const lat2 = scooterPosition['latitude'];
159
160
        const lon1 = userPosition['longitude'];
161
        const lon2 = scooterPosition['longitude'];
162
163
        const R = 6371; //Radius of earth
164
165
166
        const dLat = degrees2Radius(lat2 - lat1);
167
        const dLon = degrees2Radius(lon2 - lon1);
168
169
        const a =
170
             Math.sin(dLat/2) * Math.sin(dLat/2) +
171
             Math.cos(degrees2Radius(lat1)) * Math.cos(degrees2Radius(lat2)) *
172
             Math.sin(dLon/2) * Math.sin(dLon/2)
173
             ;
174
175
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
176
177
        const proximity = R * c;
178
179
        // Return distance in meters
180
        return proximity * 1000
181
    },
182
183
    checkIfValidScooter: async function checkIfValidScooter(scooterId: string, currentCity:object) {
184
        const getScooters = await scooterModel.getScooters(currentCity);
185
        const scooters = getScooters['cityScooters'];
186
    
187
        
188
        
189
        for (let i = 0; i < scooters.length; i++) {
190
            
191
            if (scooters[i]['_id'] === scooterId) {                
192
                return scooters[i];
193
            }
194
        }
195
        return false;
196
    },
197
198
    getSpecificScooter: async function getSpecificScooter(scooterId: string) {
199
        const token = await storage.readToken();
200
201
        const response = await fetch(`${config.base_url}scooters/${scooterId}?api_key=${API_KEY}`, {
202
            method: 'GET',
203
            headers: {
204
                'x-access-token': token['token']
205
            }
206
        });
207
        const result = await response.json();
208
        
209
        return result;
210
    }
211
212
}
213
214
export default scooterModel;